#include "TcpServer.hpp"
#include "Protocol.hpp"
#include "Calculator.hpp"
#include "Deamon.hpp"
#include <memory>

using namespace LogModule;

using cal_fun = std::function<Response(const Request&)>;

// 一定有完整的报文吗？
// 不完整 -> 继续读 完整-> 提取 -> 反序列化 -> 计算模块处理
class Parse
{
public:
    Parse(cal_fun c) : _cal(c)
    {}

    std::string Entry(std::string &package)
    {
        // 1. 判断报文的完整性
        std::string message;
        std::string respstr;
        // 一次读到了多个报文 while 处理到没有完整报文为止
        while(Decode(package, &message))
        {
            LOG(LogLevel::DEBUG) << "Content:\n" << message;
            if(message.empty()) break;

            // 2. 反序列化, message是一个曾经是被序列化的request
            Request req;
            if(!req.Deserialize(message)) break;

            std::cout << "##############" << std::endl;
            req.Print();
            std::cout << "##############" << std::endl;
            
            // 3. 计算
            Response resp = _cal(req); 

            // 4. 序列化
            std::string res;
            resp.Serialize(res);
            LOG(LogLevel::DEBUG) << "序列化： \n" << res;

            // 5.添加长度报头字段
            Encode(res);
            LOG(LogLevel::DEBUG) << "Encode:\n" << res;

            // 6. 拼接应答
            respstr += res;
        }
        LOG(LogLevel::DEBUG) << "respstr:\n" << respstr;
        return respstr;
    }
private:
    cal_fun _cal;
};

int main()
{
    // ENABLE_CONSOLE_LOG(); 
    ENABLE_FILE_LOG();

    Deamon(false, false);

    // 1. 计算模块
    Calculator mycal;

    // 2. 解析模块
    Parse myParse([&mycal](const Request& req){ 
        return mycal.Execute(req);
    }); 
    
    // 3. 通信模块, 只负责进行 IO
    std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>([&myParse](std::string &package){
        return myParse.Entry(package);
    });

    tsvr->InitServer();
    tsvr->Start();

    return 0;
}